home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / CNews / Source / expire / updatemin.c < prev   
Encoding:
C/C++ Source or Header  |  1991-10-02  |  3.8 KB  |  217 lines

  1. /*
  2.  * updatemin - update the "min" fields in the active file
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <string.h>
  8. #include <signal.h>
  9. #include <errno.h>
  10. #include "fixerrno.h"
  11.  
  12. #ifndef BERKDIR
  13. #include <dirent.h>
  14. #else
  15. #include <sys/dir.h>
  16. #define    dirent    direct
  17. #endif
  18.  
  19. #include "config.h"
  20. #include "fgetmfs.h"
  21. #include "alloc.h"
  22.  
  23. void fail();
  24. void nfail();
  25. void catch();
  26. void slash();
  27. long lowest();
  28.  
  29. char newname[] = "active.tmp";
  30.  
  31. char *progname;
  32.  
  33. extern long atol();
  34.  
  35. /*
  36.  - main - parse arguments and handle options
  37.  */
  38. main(argc, argv)
  39. int argc;
  40. char *argv[];
  41. {
  42.     DIR *d;
  43.     register FILE *a;
  44.     register FILE *new;
  45.     register char *line;
  46. #    define    NF    4
  47.     char *field[NF];
  48.     register int nf;
  49.     register long min;
  50.     register char *name;
  51.     char minstr[6];
  52.     register int i;
  53.  
  54.     progname = argv[0];
  55.  
  56.     cd(ctlfile((char *)NULL));
  57.     (void) umask(newsumask());
  58.  
  59.     catch(SIGINT);
  60.     catch(SIGQUIT);
  61.     catch(SIGHUP);
  62.     catch(SIGTERM);
  63.     newslock();
  64.  
  65.     a = fopen("active", "r");
  66.     if (a == NULL)
  67.         fail("cannot open `%s'", ctlfile("active"));
  68.     if (fopen(newname, "r") != NULL)
  69.         nfail("`%s' already exists", newname);
  70.     new = fopen(newname, "w");
  71.     if (new == NULL)
  72.         fail("cannot create `%s'", ctlfile(newname));
  73.  
  74.     cd(fullartfile((char *)NULL));
  75.     while ((line = fgetms(a)) != NULL) {
  76.         i = strlen(line);
  77.         if (i > 0 && line[i-1] == '\n')
  78.             line[i-1] = '\0';
  79.         nf = split(line, field, NF, "");
  80.         if (nf != NF)
  81.             nfail("bad number of fields in `%s ...'", field[0]);
  82.         name = strsave(field[0]);
  83.         slash(name);
  84.         d = opendir(artfile(name));
  85.         if (d != NULL) {
  86.             min = lowest(d);
  87.             if (min < 0)        /* no articles */
  88.                 min = atol(field[1])+1;
  89.             closedir(d);
  90.         } else                /* no directory */
  91.             min = atol(field[2]);
  92.         fprintf(new, "%s %s ", field[0], field[1]);
  93.         if (min < 10000) {    /* insist on at least five digits */
  94.             sprintf(minstr, "%ld", min);
  95.             fprintf(new, "%s", "00000"+strlen(minstr));
  96.         }
  97.         fprintf(new, "%ld %s\n", min, field[3]);
  98.         if (ferror(new))
  99.             fail("unable to write `%s'", ctlfile(newname));
  100.         free(name);
  101.         free(line);
  102.     }
  103.  
  104.     if (nfclose(new) == EOF)
  105.         fail("close failed on `%s'", ctlfile(newname));
  106.     cd(ctlfile((char *)NULL));
  107.     (void) unlink("active.old");
  108.     if (link("active", "active.old") < 0)
  109.         fail("can't link `active' to `active.old'", "");
  110.     if (unlink("active") < 0)
  111.         fail("can't unlink `active'", "");
  112.     if (link(newname, "active") < 0) {
  113.         if (link("active.old", "active") < 0)
  114.             fail("disaster -- cannot recover `active'!!", "");
  115.         else
  116.             fail("can't link in new `active' -- old one used", "");
  117.     }
  118.     if (unlink(newname) < 0)
  119.         fail("can't unlink `%s'", newname);
  120.     newsunlock();
  121.  
  122.     exit(0);
  123. }
  124.  
  125. /*
  126.  - lowest - find numerically-lowest name in directory
  127.  */
  128. long                /* lowest; -1 if none */
  129. lowest(d)
  130. register DIR *d;
  131. {
  132.     register struct dirent *dp;
  133.     register long this;
  134.     register long min = -1;
  135.     register int any = 0;
  136.  
  137.     while ((dp = readdir(d)) != NULL) {
  138.         if (strspn(dp->d_name, "0123456789") == strlen(dp->d_name)) {
  139.             this = atol(dp->d_name);
  140.             if (this < min || !any) {
  141.                 min = this;
  142.                 any = 1;
  143.             }
  144.         }
  145.     }
  146.  
  147.     return(min);
  148. }
  149.  
  150. /*
  151.  - slash - convert dots to slashes in string
  152.  */
  153. void
  154. slash(s)
  155. char *s;
  156. {
  157.     register char *p = s;
  158.  
  159.     while ((p = strchr(p, '.')) != NULL)
  160.         *p = '/';
  161. }
  162.  
  163. /*
  164.  - interrupt - signal handler
  165.  */
  166. void
  167. interrupt()
  168. {
  169.     nfail("interrupted", "");
  170. }
  171.  
  172. /*
  173.  - catch - set up to catch a signal
  174.  */
  175. void
  176. catch(sig)
  177. int sig;
  178. {
  179.     if (signal(sig, SIG_IGN) != SIG_IGN)
  180.         (void) signal(sig, interrupt);
  181. }
  182.  
  183. /*
  184.  - fail - some sort of error occurred
  185.  */
  186. void
  187. fail(s1, s2)
  188. char *s1;
  189. char *s2;
  190. {
  191.     /* possibly should rm newname, but it may be important evidence */
  192.     errunlock(s1, s2);
  193. }
  194.  
  195. /*
  196.  - nfail - fail but with errno meaningless
  197.  */
  198. void
  199. nfail(s1, s2)
  200. char *s1;
  201. char *s2;
  202. {
  203.     extern int errno;
  204.  
  205.     errno = 0;
  206.     fail(s1, s2);
  207. }
  208.  
  209. /*
  210.  - unprivileged - keep the configuration stuff happy
  211.  */
  212. void
  213. unprivileged(reason)
  214. char *reason;
  215. {
  216. }
  217.